package com.gcloud.controller.slb.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.gcloud.controller.ResourceProviders;
import com.gcloud.controller.network.provider.INetworkProvider;
import com.gcloud.controller.slb.dao.LoadBalancerDao;
import com.gcloud.controller.slb.dao.VServerGroupDao;
import com.gcloud.controller.slb.entity.LoadBalancer;
import com.gcloud.controller.slb.entity.VServerGroup;
import com.gcloud.controller.slb.model.DescribeVServerGroupAttributeResponse;
import com.gcloud.controller.slb.provider.IVServerGroupProvider;
import com.gcloud.controller.slb.service.IVServerGroupService;
import com.gcloud.core.condition.ConditionalSlb;
import com.gcloud.core.exception.GCloudException;
import com.gcloud.header.enums.ResourceType;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Transactional(propagation = Propagation.REQUIRES_NEW)
@ConditionalSlb
public class VServerGroupServiceImpl implements IVServerGroupService {
	@Autowired
	IVServerGroupProvider provider;
	@Autowired
	VServerGroupDao vServerGroupDao;
	@Autowired
	private LoadBalancerDao lberDao;

	public String createVServerGroup(String loadBalancerId, String vServerGroupName, String vServerGroupProtocol) {
		LoadBalancer lber = lberDao.getById(loadBalancerId);
		if(lber == null) {
			throw new GCloudException("Not Found");
		}
		return getProviderOrDefault().createVServerGroup(loadBalancerId, vServerGroupName, vServerGroupProtocol);
	}

	public void setVServerGroupAttribute(String vServerGroupId, String vServerGroupName) {
		VServerGroup vsg = vServerGroupDao.getById(vServerGroupId);
		if (vsg == null) {
			throw new GCloudException("Not Found");
		}
		provider.setVServerGroupAttribute(vsg.getProviderRefId(), vServerGroupName);
		VServerGroup vServerGroup = new VServerGroup();
		vServerGroup.setId(vServerGroupId);
		List<String> updateFields = new ArrayList<>();
		updateFields.add(vServerGroup.updateName(vServerGroupName));
		vServerGroupDao.update(vServerGroup, updateFields);
	}

	public List<VServerGroup> describeVServerGroups(String loadBalancerId) {
		return vServerGroupDao.findByProperty("loadBalancerId", loadBalancerId);
	}

	public DescribeVServerGroupAttributeResponse describeVServerGroupAttribute(String vServerGroupId) {
		VServerGroup vsg = vServerGroupDao.getById(vServerGroupId);
		if (vsg == null) {
			throw new GCloudException("Not Found");
		}
		DescribeVServerGroupAttributeResponse response= provider.describeVServerGroupAttribute(vsg.getProviderRefId());
		response.setvServerGroupId(vsg.getId());
		return response;
	}

	public void deleteVServerGroup(String vServerGroupId) {
		VServerGroup vsg = vServerGroupDao.getById(vServerGroupId);
		if (vsg == null) {
			throw new GCloudException("Not Found");
		}
		vServerGroupDao.deleteById(vServerGroupId);
		provider.deleteVServerGroup(vsg.getProviderRefId());
	}

	public void addVServerGroupBackendServers(String vServerGroupId, String backendServers) {
		VServerGroup vsg = vServerGroupDao.getById(vServerGroupId);
		if (vsg == null) {
			throw new GCloudException("Not Found");
		}
		provider.addVServerGroupBackendServers(vsg.getProviderRefId(), backendServers);
	}

	public void removeVServerGroupBackendServers(String vServerGroupId, String backendServers) {
		VServerGroup vsg = vServerGroupDao.getById(vServerGroupId);
		if (vsg == null) {
			throw new GCloudException("Not Found");
		}
		provider.removeVServerGroupBackendServers(vsg.getProviderRefId(), backendServers);
	}

	public void setVServerGroupBackendServers(String vServerGroupId, String backendServers) {
		VServerGroup vsg = vServerGroupDao.getById(vServerGroupId);
		if (vsg == null) {
			throw new GCloudException("Not Found");
		}
		provider.setVServerGroupBackendServers(vsg.getProviderRefId(), backendServers);
	}

	private IVServerGroupProvider getProviderOrDefault() {
		IVServerGroupProvider provider = ResourceProviders.getDefault(ResourceType.VSERVER_GROUP);
		return provider;
	}

	private IVServerGroupProvider getProvider(int providerType) {
		return ResourceProviders.checkAndGet(ResourceType.VSERVER_GROUP, providerType);
	}
}
